/**
 * Copyright (c) 2016-2020 人人开源 All rights reserved.
 * <p>
 * https://www.renren.io
 * <p>
 * 版权所有，侵权必究！
 */

package io.renren.job;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobContext;
import com.xxl.job.core.handler.annotation.XxlJob;
import io.renren.com.qywt.dto.AftersaleFinanceCollectDTO;
import io.renren.com.qywt.entity.*;
import io.renren.com.qywt.service.*;
import io.renren.commons.security.user.UserDetail;
import io.renren.commons.tools.enums.DeleteEnum;
import io.renren.commons.tools.utils.DateUtils;
import io.renren.commons.tools.utils.Result;
import io.renren.feign.UserFeignClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;

/**
 * 财务结算
 */
@Slf4j
@Component
public class FinanceJob {
    @Autowired
    private AftersaleFinanceCollectService aftersaleFinanceCollectService;
    @Autowired
    TaskStorageFeeService taskStorageFeeService;
    @Autowired
    TaskReturnFeeService taskReturnFeeService;
    @Autowired
    TaskPurchaseReturnFeeService taskPurchaseReturnFeeService;
    @Autowired
    TaskLocationFeeService taskLocationFeeService;
    @Autowired
    TaskEjectFeeService taskEjectFeeService;
    @Autowired
    TaskCarriageFeeService taskCarriageFeeService;
    @Autowired
    private AftersaleStorageFeeService storageFeeService;
    @Autowired
    private AftersaleReturnFeeService returnFeeService;
    @Autowired
    private AftersalePurchasereturnFeeService purchaseReturnFeeService;
    @Autowired
    private AftersaleLocationFeeService locationFeeService;
    @Autowired
    private AftersaleEjectFeeService ejectFeeService;
    @Autowired
    private AftersaleCarriageFeeService carriageFeeService;
    @Autowired
    private UserFeignClient userFeignClient;

    public static volatile List<AftersaleStorageFeeEntity> storageFeeList=new ArrayList<>();
    public static volatile List<AftersaleReturnFeeEntity> returnFeeList=new ArrayList<>();
    public static volatile List<AftersalePurchasereturnFeeEntity> purchaseReturnFeeList=new ArrayList<>();
    public static volatile List<AftersaleLocationFeeEntity> locationFeeList=new ArrayList<>();
    public static volatile List<AftersaleEjectFeeEntity> ejectFeeList=new ArrayList<>();
    public static volatile List<AftersaleCarriageFeeEntity> carriageFeeList=new ArrayList<>();

    @XxlJob("financeHandler")
    public ReturnT<String> financeHandler() throws Exception {
        XxlJobContext xxlJobContext = XxlJobContext.getXxlJobContext();
        String param=xxlJobContext.getJobParam();
        JSONObject json= JSON.parseObject(param);
        String userName=json.getString("userName");
        Result<UserDetail> userResult=userFeignClient.getUserDetail(userName);
        String batchNo=json.getString("batchNo");
        AftersaleFinanceCollectDTO dto=null;
        if(StringUtils.isBlank(batchNo)){//执行当前时间前一天跑批任务
            log.info("xxl-job 正在执行，参数：{}", userName);
            dto=new AftersaleFinanceCollectDTO();
            Date collectDate=DateUtils.addDateDays(new Date(),-1);
            batchNo=DateUtils.format(collectDate,DateUtils.DATE_PATTERN).replaceAll("-","");
            dto.setBatchNo(batchNo);
            dto.setCollectDate(collectDate);
        }else{//执行指定时间的跑批任务
            log.info("xxl-job 正在执行，参数：{}", userName,batchNo);
            dto=aftersaleFinanceCollectService.getByBatchNo(batchNo);
            if(ObjectUtil.isNotNull(dto)){
                aftersaleFinanceCollectService.deleteFeeByBatchNo(batchNo,userResult.getData());
            }else{
                dto=new AftersaleFinanceCollectDTO();
                String collectDate=batchNo.substring(0,4)+"-"+batchNo.substring(4,6)+"-"+batchNo.substring(6,8);
                dto.setBatchNo(batchNo);
                dto.setCollectDate(DateUtils.stringToDate(collectDate+" 00:00:00",DateUtils.DATE_TIME_PATTERN));
            }
        }
        if(ObjectUtil.isNotNull(userResult.getData())){
            CountDownLatch countDownLatch = new CountDownLatch(1);
            final AftersaleFinanceCollectDTO finalDto=dto;

            /*new Thread(()->{
                storageFeeList=taskStorageFeeService.getReceiptDetail(userResult.getData(),finalDto);
                storageFeeService.insertBatch(storageFeeList);
                countDownLatch.countDown();
            }).start();

            new Thread(()->{
                returnFeeList=taskReturnFeeService.getReturnInfoList(userResult.getData(),finalDto);
                returnFeeService.insertBatch(returnFeeList);
                countDownLatch.countDown();
            }).start();

            new Thread(()->{
                purchaseReturnFeeList=taskPurchaseReturnFeeService.getPurchaseReturnInfoList(userResult.getData(),finalDto);
                purchaseReturnFeeService.insertBatch(purchaseReturnFeeList);
                countDownLatch.countDown();
            }).start();*/

            new Thread(()->{
                locationFeeList=taskLocationFeeService.getInventoryInfoList(userResult.getData(), finalDto);
                locationFeeService.insertBatch(locationFeeList);
                countDownLatch.countDown();
            }).start();

            /*new Thread(()->{
                ejectFeeList=taskEjectFeeService.getShipmentInfoList(userResult.getData(),finalDto);
                ejectFeeService.insertBatch(ejectFeeList);
                countDownLatch.countDown();
            }).start();

            new Thread(()->{
                carriageFeeList=taskCarriageFeeService.getCarriageInfoList(userResult.getData(),finalDto);
                carriageFeeService.insertBatch(carriageFeeList);
                countDownLatch.countDown();
            }).start();*/

            try {
                countDownLatch.await();
            }catch (InterruptedException ex){
                ex.printStackTrace();
            }

            if(countDownLatch.getCount()==0){
                Optional<BigDecimal> storageFee=storageFeeList.stream().map(AftersaleStorageFeeEntity::getProdFee).reduce(BigDecimal::add);
                Optional<BigDecimal> returnFee=returnFeeList.stream().map(AftersaleReturnFeeEntity::getReturnFee).reduce(BigDecimal::add);
                Optional<BigDecimal> purchaseReturnFee=purchaseReturnFeeList.stream().map(AftersalePurchasereturnFeeEntity::getReturnFee).reduce(BigDecimal::add);
                Optional<BigDecimal> locationFee=locationFeeList.stream().map(AftersaleLocationFeeEntity::getLocationFee).reduce(BigDecimal::add);
                Optional<BigDecimal> ejectFee=ejectFeeList.stream().map(AftersaleEjectFeeEntity::getEjectFee).reduce(BigDecimal::add);
                Optional<BigDecimal> carriageFee=carriageFeeList.stream().map(AftersaleCarriageFeeEntity::getCarriageFee).reduce(BigDecimal::add);
                if(ObjectUtil.isNull(dto.getId())){
                    dto.setStatus(1);
                    dto.setDelFlag(DeleteEnum.NO.value());
                    dto.setTenantCode(userResult.getData().getTenantCode());
                    dto.setCreator(userResult.getData().getId());
                }
                dto.setStorageFee(storageFee.isPresent()?storageFee.get():BigDecimal.ZERO);
                dto.setReturnFee(returnFee.isPresent()?returnFee.get():BigDecimal.ZERO);
                dto.setPurchaseReturnFee(purchaseReturnFee.isPresent()?purchaseReturnFee.get():BigDecimal.ZERO);
                dto.setLocationFee(locationFee.isPresent()?locationFee.get():BigDecimal.ZERO);
                dto.setEjectFee(ejectFee.isPresent()?ejectFee.get():BigDecimal.ZERO);
                dto.setCarriageFee(carriageFee.isPresent()?carriageFee.get():BigDecimal.ZERO);

                if(ObjectUtil.isNotNull(dto.getId())){
                    aftersaleFinanceCollectService.update(dto);
                }else{
                    aftersaleFinanceCollectService.save(dto);
                }
                storageFeeList.clear();
                returnFeeList.clear();
                purchaseReturnFeeList.clear();
                locationFeeList.clear();
                ejectFeeList.clear();
                carriageFeeList.clear();
            }
        }
        return ReturnT.SUCCESS;
    }
}
